package process

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"go_example/src/chatroom/client/utils"
	"go_example/src/chatroom/common/message"
	"net"
	"os"
)

type UserProcess struct {
	//暂时不需要任何字段
}

//处理用户注册
func (this *UserProcess) Resister(userId int,
	userPwd string, userName string) (err error) {
	conn, err := net.Dial("tcp","127.0.0.1:8889")
	if err != nil {
		fmt.Println("Resister() net.Dial err=", err)
		return
	}

	defer conn.Close()

	//通过conn发送消息给服务器
	var mes message.Message
	mes.Type = message.RegisterMesType

	//创建一个RegisterMes结构体
	var registerMes message.RegisterMes
	registerMes.User.UserId = userId
	registerMes.User.UserPwd = userPwd
	registerMes.User.UserName = userName

	//将RegisterMes序列化
	data ,err := json.Marshal(registerMes)
	if err != nil {
		fmt.Println("Resister() registerMes json.Marshal err=", err)
		return
	}
	fmt.Println("data=", string(data))
	//把data赋给 mes.Data字段
	mes.Data = string(data)

	//将mes进行序列化
	data ,err = json.Marshal(mes)
	if err != nil {
		fmt.Println("Resister() mes json.Marshal err=", err)
		return
	}
	fmt.Println("mes=", string(data))

	tf := &utils.Transfer{
		Conn: conn,
	}

	//发送data给服务端
	err = tf.WritePkg(data)
	if err != nil {
		fmt.Println("注册发送信息错误 err=", err)
		return
	}

	mes, err = tf.ReadPkg()
	if err != nil {
		fmt.Println("Resister() ReadPkg err=", err)
		return
	}

	//将mes的Data部分反序列化成LoginResMes
	var registerResMes message.RegisterResMes
	err = json.Unmarshal([]byte(mes.Data), &registerResMes)
	if registerResMes.Code == 200 {
		//在客户端启动一个协程，保持和服务端的通讯，接收显示服务器反馈到客户端的信息
		fmt.Println("注册成功了，请重新登陆")
		//注册成功后退出
		os.Exit(0)
	} else {
		fmt.Println(registerResMes.Error)
		os.Exit(0)
	}
	return
}

//关联用户登陆的方法

func (this *UserProcess) Login(userId int, userPwd string) (err error) {
	//fmt.Printf("userId = %d userPwd = %s", userId, userPwd)
	//return nil
	//连接服务器
	conn, err := net.Dial("tcp","127.0.0.1:8889")
	if err != nil {
		fmt.Println("Login() net.Dial err=", err)
		return
	}

	defer conn.Close()

	//通过conn发送消息给服务器
	var mes message.Message
	mes.Type = message.LoginMesType

	//创建一个LoginMes结构体
	var loginMes message.LoginMes
	loginMes.UserId = userId
	loginMes.UserPwd = userPwd

	//将loginMes 序列化
	data ,err := json.Marshal(loginMes)
	if err != nil {
		fmt.Println("Login() loginMes json.Marshal err=", err)
		return
	}
	fmt.Println("data=", string(data))
	//把data赋给 mes.Data字段
	mes.Data = string(data)

	//将mes进行序列化
	data ,err = json.Marshal(mes)
	if err != nil {
		fmt.Println("Login() mes json.Marshal err=", err)
		return
	}
	fmt.Println("mes=", string(data))

	//这个时候data就是我们要发送的消息
	//先获取到data的长度，转成可以表示长度的byte切片,把data的长度发送给服务器
	var pkgLen uint32
	pkgLen = uint32(len(data))
	var buf [4]byte
	binary.BigEndian.PutUint32(buf[0:4], pkgLen)

	//发送这个长度
	n, err := conn.Write(buf[0:4])
	if n != 4 || err != nil {
		fmt.Println("Login() conn.Write(buf) err=", err)
		return
	}
	//fmt.Printf("客户端,发送消息的长度=%d 内容=%s", len(data), string(data))
	//发送消息本身
	_, err = conn.Write(data)
	if err != nil {
		fmt.Println("Login() conn.Write(data) err=", err)
		return
	}

	//处理用户服务端返回的消息
	tf := &utils.Transfer{
		Conn: conn,
	}
	mes, err = tf.ReadPkg()
	//mes, err = utils.ReadPkg(conn)

	//将mes的Data部分反序列化成LoginResMes
	var loginResMes message.LoginResMes
	err = json.Unmarshal([]byte(mes.Data), &loginResMes)
	if loginResMes.Code == 200 {
		//初始化CurUser
		CurUser.Conn = conn
		CurUser.UserId = userId
		CurUser.UserStatus= message.UserOnline
		//显示当前在线用户列表
		fmt.Println("当前用户在线列表如下：")
		for _, v := range loginResMes.UsersId {
			//不显示自己在线
			if v == userId {
				continue
			}

			fmt.Printf("用户id=%v\t", v)
			//完成客户端onlineUsers的初始化
			user := &message.User{
				UserId:     v,
				UserStatus: message.UserOnline,
			}
			onlineUsers[v] = user
		}
		fmt.Print("\n\n")

		//在客户端启动一个协程，保持和服务端的通讯，接收显示服务器反馈到客户端的信息
		go ServerProcessMes(conn)

		//登陆成功后，显示登陆后的菜单
		for true {
			ShowMenu(userId)
		}
	} else if loginResMes.Code == 500 {
		fmt.Println(loginResMes.Error)
	}
	return
}